#include <QPushButton>
#include <QStandardItemModel>
#include <QTabWidget>
#include "allow-remove-data-settings-form.h"
#include "icon-store.h"
#include "settings.h"
#include "settings-dialog.h"
#include "ui_settings-dialog.h"
#include "widget-helper.h"


SettingsDialog::SettingsDialog (QWidget* parent) :
    QDialog(parent), ui(new Ui::SettingsDialog), m_showCategoryRequested(-1), m_showTabRequested(-1)
{
    ui->setupUi(this);
}


SettingsDialog::~SettingsDialog()
{
    delete ui;
}


void SettingsDialog::initialize()
{
    setupForms();
    setupCategoryView();
    setupAppearance();
    setupConnections();
    loadSettings();
}

void SettingsDialog::setupForms()
{
    while (ui->stackedWidget->count())
        ui->stackedWidget->removeWidget(ui->stackedWidget->widget(0));

    // add appearance tab widget
    QTabWidget* databaseTabWidget = new QTabWidget(this);
    databaseTabWidget->setObjectName("databaseTabWidget");
    ui->stackedWidget->addWidget(databaseTabWidget);

    // add data tab
    QWidget* dataWidget = new QWidget(this);
    dataWidget->setLayout(new QGridLayout(dataWidget));
    databaseTabWidget->addTab(dataWidget, "Dane");

    // add allow remove data settings form
    AllowRemoveDataSettingsForm* allowRemoveDataSettingsForm = new AllowRemoveDataSettingsForm(this);
    m_settingForms.append(allowRemoveDataSettingsForm);
    dataWidget->layout()->addWidget(allowRemoveDataSettingsForm);

    // add spacer
    dataWidget->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding));
}


void SettingsDialog::setupCategoryView()
{
    int iconSize = 48;
    QStandardItemModel* categoryModel = new QStandardItemModel(this);
    categoryModel->appendRow(new QStandardItem(IconStore::icon(IconStore::ServerDatabase, iconSize), "Baza danych"));
    ui->categoryView->setModel(categoryModel);
}


void SettingsDialog::setupAppearance()
{
    setWindowFlags(Qt::Window);
    setWindowIcon(IconStore::icon(IconStore::PreferencesSystem, 16));
    ui->buttonBox->addButton(QDialogButtonBox::Apply);
    foreach (AbstractSettingsForm* settingsForm, m_settingForms)
        settingsForm->layout()->setContentsMargins(0, 0, 0, 0);
    resize(sizeHint());
}


void SettingsDialog::setupConnections()
{
    connect (ui->categoryView->selectionModel(), &QItemSelectionModel::currentChanged,
             this, &SettingsDialog::changeSettingsPage);
    connect (this, &SettingsDialog::accepted, this, &SettingsDialog::saveChildrenSettings);
    connect (this, &SettingsDialog::accepted, this, &SettingsDialog::saveSettings);
    connect (ui->buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked,
             this, &SettingsDialog::saveChildrenSettings);
}


void SettingsDialog::changeSettingsPage (const QModelIndex& index)
{
    ui->stackedWidget->setCurrentIndex(index.row());
}


void SettingsDialog::saveChildrenSettings()
{
    for (int i = 0; i < m_settingForms.size(); i++)
        m_settingForms.at(i)->saveSettings();
}


void SettingsDialog::saveSettings()
{
    Settings settings;
    settings.beginGroup(metaObject()->className());
    settings.setValue("geometry", saveGeometry());
    settings.setValue("currentCategory", ui->categoryView->selectionModel()->selectedIndexes().at(0).row());

    settings.beginWriteArray("currentTabs");
    int arrayIndex = 0;
    for (int i = 0; i < ui->stackedWidget->count(); i++)
    {
        QTabWidget* tabWidget = qobject_cast<QTabWidget*>(ui->stackedWidget->widget(i));
        if (tabWidget)
        {
            settings.setArrayIndex(arrayIndex);
            settings.setValue("tabWidgetName", tabWidget->objectName());
            settings.setValue("currentTab", tabWidget->currentIndex());
            arrayIndex++;
        }
    }
    settings.endArray();
}


void SettingsDialog::loadSettings()
{
    Settings settings;
    settings.beginGroup(metaObject()->className());

    QByteArray geometry = settings.value("geometry").toByteArray();
    if (!geometry.isEmpty())
        restoreGeometry(geometry);

    if (m_showCategoryRequested != -1 && m_showTabRequested != -1)
    {
        ui->categoryView->setCurrentIndex(ui->categoryView->model()->index(m_showCategoryRequested, 0));
        QTabWidget* tabWidget = qobject_cast<QTabWidget*>(ui->stackedWidget->widget(m_showCategoryRequested));
        if (tabWidget)
            tabWidget->setCurrentIndex(m_showTabRequested);
        return;
    }

    int currentCategory = settings.value("currentCategory", 0).toInt();
    ui->categoryView->setCurrentIndex(ui->categoryView->model()->index(currentCategory, 0));

    int arraySize = settings.beginReadArray("currentTabs");
    if (arraySize)
    {
        QMap<QString,QTabWidget*> tabWidgetMap;
        for (int i = 0; i < ui->stackedWidget->count(); i++)
        {
            QTabWidget* tabWidget = qobject_cast<QTabWidget*>(ui->stackedWidget->widget(i));
            if (tabWidget && !tabWidget->objectName().isEmpty())
                tabWidgetMap.insert(tabWidget->objectName(), tabWidget);
        }

        for (int i = 0; i < arraySize; i++)
        {
            settings.setArrayIndex(i);
            QTabWidget* tabWidget = tabWidgetMap.value(settings.value("tabWidgetName").toString());
            if (tabWidget)
                tabWidget->setCurrentIndex(settings.value("currentTab", 0).toInt());
        }
    }
}


void SettingsDialog::setCurrentView (int category, int tab)
{
    if (category >= 0 && tab >= 0)
    m_showCategoryRequested = category;
    m_showTabRequested = tab;
}
